package day4.HomeWork;

import day4.Persion;
import day4.Student;

import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.Arrays;

public class homeWork {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, IOException {
        //testA();

        //testB();

        ChooseA();

        //ChooseB();

    }

    /*a.通过反射定义一个方法可以实现修改任意对象的属性值
    通过反射定义一个方法可以实现获取任意对象的属性值
    提示：设置属性  setProperty(对象，属性名,新的属性值)
    获取属性  getProperty(对象，属性名)*/

    public static void ChooseA() {
        Student s = new Student();
        set(s, "name", "wuxi");
        set(s, "age", 22);
        set(s, "sex", "男");
        Object value1 = get(s, "name");
        Object value2 = get(s, "age");
        Object value3 = get(s, "sex");
        System.out.println(value1);
        System.out.println(value2);
        System.out.println(value3);
    }

    public static void set(Object o, String name, Object value) {

        Class c = o.getClass();
        Field f = null;
        try {
            f = c.getDeclaredField(name);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        try {
            f.set(o, value);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    public static Object get(Object o, String name) {
        Object value = null;

        try {
            Class c = o.getClass();
            Field f = c.getDeclaredField(name);
            f.setAccessible(true);
            value = f.get(o);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return value;
    }

    public static Object ChooseA(Object o, String name, Object o1) {
        Object value = null;
        try {
            Class c = o.getClass();
            Field field = c.getDeclaredField("name");
            field.setAccessible(true);
            Student s = new Student();
            field.set(s, o1);
            value = field.get(s);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return name + "的属性值为:" + value;
    }

    //a.设计一个类简单的类 有参构造方法私有化了  通过反射使用有参构造把该对象创建出来?
    public static void testA() throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class c = Class.forName("day4.Persion");
        Constructor con = c.getDeclaredConstructor(Integer.class);
        con.setAccessible(true);
        Persion p = (Persion) con.newInstance(100);
        System.out.println(p);

    }

    //b.使用反射创建长度为5的String数组,为数组的前三个元素赋值："DemoA", "B", "C"。
    //打印数组的内容。(提示:Array.newInstance 来实例化数组)
    public static void testB() {
        Object o = Array.newInstance(String.class, 5);
        Array.set(o, 0, "DemoA");
        Array.set(o, 1, "B");
        Array.set(o, 2, "C");
        for (int i = 0; i < Array.getLength(o); i++) {
            System.out.println(Array.get(o, i));
        }

    }

    //通过一个类自定义的类  属性 任意  方法任意编写
    //  通过反射获取类的所有属性和方法  然后 将获取的数据
    //  写入到result.txt中  内容如下:
    //  方法有:
    //  属性有:
    //  构造方法有:
    public static void ChooseB() throws IOException {
        Class c = Student.class;
        Field[] fs = c.getDeclaredFields();
        Method[] ms = c.getDeclaredMethods();
        Constructor[] cs = c.getDeclaredConstructors();
        StringBuilder sb = new StringBuilder();
        sb.append("方法有:\n");
        for (Method m : ms) {
            String name = m.getName();
            Class[] classes = m.getParameterTypes();
            sb.append("方法名: " + name + "   类型: " + Arrays.toString(classes) + "\n");
        }

        sb.append("属性有:\n");
        for (Field f : fs) {
            String name = f.getName();
            Class classes = f.getType();
            sb.append("属性名: " + name + "   类型: " + classes + "\n");
        }

        sb.append("构造方法有:\n");
        for (Constructor con : cs) {
            String name = con.getName();
            sb.append("构造方法: " + name + "\n");
        }

        FileWriter fw = new FileWriter("d://io//result.txt");
        fw.write(sb.toString());
        fw.close();
        System.out.println(sb);
    }
}
